<template>
  <a-form-model
    v-if="itemSearch.length > 0"
    ref="formInline"
    layout="inline"
    :model="formInline"
  >
    <a-form-model-item
      v-for="(element, index) in itemSearch"
      v-show="showIf(element)"
      :key="index"
      :label="element.label"
      :prop="element.key"
    >
      <labelSearch
        v-if="element.type == 'labelSelect'"
        v-model="formInline[element.key]"
        :table="element.labelSelect.table"
        :field="element.labelSelect.field"
        width="180px"
        @change="(...arr) => elementChange(element, ...arr)"
      />
      <a-select
        v-else-if="element.type == 'lastFollowSelect'"
        v-model="formInline[element.key]"
        style="width: 160px;"
        allow-clear
        placeholder="最后跟进时间筛选"
        @change="(...arr) => elementChange(element, ...arr)"
      >
        <a-select-opt-group>
          <span slot="label">未跟进</span>
          <a-select-option value="0,1">
            本周未跟进
          </a-select-option>
          <a-select-option value="0,2">
            本月未跟进
          </a-select-option>
          <a-select-option value="0,3">
            3个月内未跟进
          </a-select-option>
          <a-select-option value="0,4">
            半年未跟进
          </a-select-option>
          <a-select-option value="0,5">
            一年未跟进
          </a-select-option>
        </a-select-opt-group>
        <a-select-opt-group>
          <span slot="label">已跟进</span>
          <a-select-option value="1,1">
            本周已跟进
          </a-select-option>
          <a-select-option value="1,2">
            本月已跟进
          </a-select-option>
          <a-select-option value="1,3">
            3个月已跟进
          </a-select-option>
          <a-select-option value="1,4">
            半年已跟进
          </a-select-option>
          <a-select-option value="1,5">
            一年已跟进
          </a-select-option>
        </a-select-opt-group>
      </a-select>
      <edit
        v-else
        v-model="formInline[element.key]"
        :element="element"
        :debug="debug"
        :style="{
          ...element.style,
          width: element.width ? element.width : undefined,
        }"
        @change="(...arr) => elementChange(element, ...arr)"
      />
    </a-form-model-item>

    <span v-if="itemSearchMore.length > 0" v-show="moreSearchVisible">
      <a-form-model-item
        v-for="(element, index) in itemSearchMore"
        v-show="showIf(element)"
        :key="index"
        :label="element.label"
        :prop="element.key"
      >
        <labelSearch
          v-if="element.type == 'labelSelect'"
          v-model="formInline[element.key]"
          :table="element.labelSelect.table"
          :field="element.labelSelect.field"
          width="180px"
          @change="(...arr) => elementChange(element, ...arr)"
        />
        <a-select
          v-else-if="element.type == 'lastFollowSelect'"
          v-model="formInline[element.key]"
          style="width: 160px;"
          allow-clear
          placeholder="最后跟进时间筛选"
          @change="(...arr) => elementChange(element, ...arr)"
        >
          <a-select-opt-group>
            <span slot="label">未跟进</span>
            <a-select-option value="0,1">
              本周未跟进
            </a-select-option>
            <a-select-option value="0,2">
              本月未跟进
            </a-select-option>
            <a-select-option value="0,3">
              3个月内未跟进
            </a-select-option>
            <a-select-option value="0,4">
              半年未跟进
            </a-select-option>
            <a-select-option value="0,5">
              一年未跟进
            </a-select-option>
          </a-select-opt-group>
          <a-select-opt-group>
            <span slot="label">已跟进</span>
            <a-select-option value="1,1">
              本周已跟进
            </a-select-option>
            <a-select-option value="1,2">
              本月已跟进
            </a-select-option>
            <a-select-option value="1,3">
              3个月已跟进
            </a-select-option>
            <a-select-option value="1,4">
              半年已跟进
            </a-select-option>
            <a-select-option value="1,5">
              一年已跟进
            </a-select-option>
          </a-select-opt-group>
        </a-select>
        <edit
          v-else
          v-model="formInline[element.key]"
          :element="element"
          :debug="debug"
          :style="{
            width: element.width ? element.width : undefined,
            ...element.style,
          }"
          @change="(...arr) => elementChange(element, ...arr)"
        />
      </a-form-model-item>
    </span>

    <a-form-model-item v-if="itemSearchMore.length > 0">
      <a @click="moreSearchVisible = !moreSearchVisible">
        <template v-if="!moreSearchVisible">
          <a-icon type="down" /> 更多
        </template>
        <template v-else> <a-icon type="up" /> 收起 </template>
      </a>
    </a-form-model-item>

    <template v-if="debug">
      <pre>{{ formInline }}</pre>
    </template>
  </a-form-model>
</template>

<script>
/*
item 子项说明
	key		string	数据项key
	label	string	左侧描述，可为空
  placeholder string 输入框提示信息
	style	object	除width外的样式
	width	string	长度
  more  bool    是否更多查询
	showIf	object	满足里面所有项才显示， undefined 不启动判断
	hideIf	object	满足里面所有项才隐藏， undefined 不启动判断
	type	show
		内容		value 值
		key		可为空

	扩展子项
		radio	bool 	是否单选， 单选string或number  多选 数组
		change (formInline, value, extData, this) => {}
				this为编辑器的主体， 以下一样

		type	select
			下啦选择
			selectArray	array 	下来数据 {value: "值", label: "标题"}

		type	radio
			buttonStyle		radio类型	风格样式，目前有描边和填色两种风格	outline | solid
			radioArray	array 	下来数据 {value: "值", label: "标题"}

		type	checkbox
			checkboxArray	array 	下来数据 {value: "值", label: "标题"}

		type	switch
			checkedLabel	string 	开启时候的文本描述
			unCheckedLabel	string 	关闭时候的文本描述

		type	number
			number	{min:最小值数字, max: 最大值数字}	数字区间限制

		type	systemArea
			systemArea {
				table: 表,
				field: 字段,
        code: 编码,
				disabled: 是否可选
			}
			selected	bool	为空时自动选择第一个

		type	admin-select

		type	data-select
			searchMap	object	查询条件
			url			string	获取数据url
			init		function 初始化显示数据  返回 [{ value:值, label:显示内容, data:数据对象}]
			selected	bool	为空时自动选择第一个

    type  date-picker
      disabledDate Function disabledDate(current) {
        // Can not select days before today and today
        return current && current < moment().endOf('day');
      },

    type  range-picker
    type  tooltip

	type	hidden
		隐藏表单传递
*/

export default {
  components: {
    edit: () => import("./edit"),
    labelSearch: () => import("@/components/label-group/search"),
  },
  props: {
    debug: {
      type: Boolean,
      default: false,
    },
    keys: {
      type: Object,
      default: () => {
        return {}
      },
    },
    item: {
      type: Array,
      default: () => {
        return undefined
      },
    },
    itemMore: {
      type: Array,
      default: () => {
        return undefined
      },
    },
  },
  data() {
    return {
      moreSearchVisible: false,
      itemSearch: [],
      itemSearchMore: [],
      formInline: {},
      timeoutObj: undefined,
    }
  },
  computed: {
    primaryKey: function () {
      return JSON.stringify(this.item)
    },
    primaryKeys: function () {
      return JSON.stringify(this.keys)
    },
  },
  watch: {
    primaryKey: function () {
      this.pageInit()
    },
    primaryKeys: function () {
      this.initKeys()
    },
  },
  mounted() {
    this.pageInit()
  },
  methods: {
    initElement(element) {
      switch (element.type) {
        case "data-select":
          if (element.init) break
          if (
            element.ext &&
            element.ext.value &&
            this.$func.isArray(element.ext.value) &&
            element.ext.label &&
            this.$func.isArray(element.ext.label)
          ) {
            element.init = (arr) => {
              let dataArr = []
              if (arr && this.$func.isArray(arr) && arr.length > 0) {
                for (let ii in arr) {
                  let value = arr[ii],
                    label = arr[ii]

                  for (let jj in element.ext.value) {
                    if (
                      !Object.prototype.hasOwnProperty.call(
                        value,
                        element.ext.value[jj]
                      )
                    ) {
                      break
                    }
                    value = value[element.ext.value[jj]]
                  }

                  for (let jj in element.ext.label) {
                    if (
                      !Object.prototype.hasOwnProperty.call(
                        label,
                        element.ext.label[jj]
                      )
                    ) {
                      break
                    }
                    label = label[element.ext.label[jj]]
                  }
                  dataArr.push({
                    value: value,
                    label: label,
                    data: arr[ii],
                  })
                }
              }
              return dataArr
            }
          } else {
            element.init = (arr) => {
              let dataArr = []
              if (arr) {
                for (let ii in arr) {
                  dataArr.push({
                    value: ii,
                    label: arr[ii],
                  })
                }
              }
              return dataArr
            }
          }
          break
        default:
          break
      }
      return element
    },
    pageInit() {
      this.formInline = {}
      this.itemSearch = []
      this.itemSearchMore = []

      for (let ii in this.item) {
        let element = this.initElement(this.item[ii])
        this.itemSearch.push({
          ...element,
        })
        this.setItem(element)
      }
      for (let ii in this.itemMore) {
        let element = this.initElement(this.itemMore[ii])
        this.itemSearchMore.push({
          ...element,
        })
        this.setItem(element)
      }

      this.initKeys()
    },
    initKeys() {
      for (let ii in this.keys) {
        this.$set(this.formInline, ii, this.keys[ii])
      }
    },
    setItem(element) {
      if (element.type == "show") return
      if (element.type == "button") return

      if (Object.prototype.hasOwnProperty.call(element, "value")) {
        this.$set(this.formInline, element.key, element.value)
      }

      if (!Object.prototype.hasOwnProperty.call(this.formInline, element.key)) {
        this.$set(this.formInline, element.key, element.value)
      }
    },
    showIf(element) {
      if (element.type === "hidden") return false

      let flag = true
      if (element.showIf) {
        let tmp = false
        for (let ii in element.showIf) {
          if (this.formInline[ii] != element.showIf[ii]) {
            tmp = true
          }
          if (tmp) break
        }
        flag = tmp == false
      }
      if (element.hideIf) {
        let tmp = false
        for (let ii in element.hideIf) {
          if (this.formInline[ii] != element.hideIf[ii]) {
            tmp = true
          }
          if (tmp) break
        }
        flag = !(tmp == false)
      }

      return flag
    },
    changeLastFollowTimeFlag(element) {
      if (!element.array2Time) return

      let timeMinKey = "",
        timeMaxKey = ""

      if (
        this.$func.isArray(element.array2Time) &&
        element.array2Time.length == 2
      ) {
        timeMinKey = element.array2Time[0]
        timeMaxKey = element.array2Time[1]
      } else {
        timeMinKey = element.array2Time + "_min"
        timeMaxKey = element.array2Time + "_max"
      }
      this.$set(this.formInline, timeMinKey, undefined)
      this.$set(this.formInline, timeMaxKey, undefined)

      if (!this.formInline[element.key]) {
        this.emitChange()
        return
      }

      let tmp = this.formInline[element.key].split(",")
      if (tmp.length != 2) {
        this.emitChange()
        return
      }

      let thisDayTime = 0
      switch (tmp[1]) {
        case "1":
          thisDayTime = this.$day.moment().startOf("week")
          break
        case "2":
          thisDayTime = this.$day.moment().startOf("month")
          break
        case "3":
          thisDayTime = this.$day.moment().subtract(3, "month").startOf("month")
          break
        case "4":
          thisDayTime = this.$day.moment().subtract(6, "month").startOf("month")
          break
        case "5":
          thisDayTime = this.$day.moment().subtract(1, "years").startOf("month")
          break
      }
      if (tmp[0] == "0") {
        thisDayTime = thisDayTime.subtract("seconds", 1)
        this.formInline[timeMaxKey] = parseInt(thisDayTime.valueOf() / 1000, 10)
      } else {
        this.formInline[timeMinKey] = parseInt(thisDayTime.valueOf() / 1000, 10)
      }
      this.emitChange()
    },
    elementChange(element) {
      let timeMinKey = "",
        timeMaxKey = "",
        dateMinKey = "",
        dateMaxKey = "",
        value2Time = "",
        value2Date = ""

      switch (element.type) {
        case "lastFollowSelect":
          if (!element.array2Time) break
          if (
            this.$func.isArray(element.array2Time) &&
            element.array2Time.length == 2
          ) {
            timeMinKey = element.array2Time[0]
            timeMaxKey = element.array2Time[1]
          } else {
            timeMinKey = element.array2Time + "_min"
            timeMaxKey = element.array2Time + "_max"
          }
          this.$set(this.formInline, timeMinKey, undefined)
          this.$set(this.formInline, timeMaxKey, undefined)

          if (this.formInline[element.key]) {
            let valueArray = this.formInline[element.key].split(",")
            if (valueArray.length != 2) {
              this.emitChange()
              return
            }
            let tmpDayTime = undefined
            switch (valueArray[1]) {
              case "1":
                tmpDayTime = this.$day.moment().startOf("week")
                break
              case "2":
                tmpDayTime = this.$day.moment().startOf("month")
                break
              case "3":
                tmpDayTime = this.$day
                  .moment()
                  .subtract(3, "month")
                  .startOf("month")
                break
              case "4":
                tmpDayTime = this.$day
                  .moment()
                  .subtract(6, "month")
                  .startOf("month")
                break
              case "5":
                tmpDayTime = this.$day
                  .moment()
                  .subtract(1, "years")
                  .startOf("month")
                break
            }
            if (!tmpDayTime) break
            if (valueArray[0] == "0") {
              tmpDayTime = tmpDayTime.subtract("seconds", 1)
              this.formInline[timeMaxKey] = parseInt(
                tmpDayTime.valueOf() / 1000,
                10
              )
            } else {
              this.formInline[timeMinKey] = parseInt(
                tmpDayTime.valueOf() / 1000,
                10
              )
            }
          }
          break
        case "labelSelect":
          if (!element.obj2Value) break
          this.$set(this.formInline, element.obj2Value, undefined)
          if (this.formInline[element.key]) {
            let dataMap = []
            for (let ii in this.formInline[element.key]) {
              let dataTmp = this.formInline[element.key][ii]
              if (
                !dataTmp ||
                !this.$func.isArray(dataTmp) ||
                dataTmp.length <= 0
              ) {
                continue
              }
              dataMap.push(ii + "=" + dataTmp.join(","))
            }
            if (dataMap.length > 0) {
              this.$set(this.formInline, element.obj2Value, dataMap.join("|"))
            }
          }

          break
        case "range-picker":
          if (!element.array2Time && !element.array2Date) break

          if (element.array2Time) {
            if (
              this.$func.isArray(element.array2Time) &&
              element.array2Time.length == 2
            ) {
              timeMinKey = element.array2Time[0]
              timeMaxKey = element.array2Time[1]
            } else {
              timeMinKey = element.array2Time + "_min"
              timeMaxKey = element.array2Time + "_max"
            }
            this.$set(this.formInline, timeMinKey, undefined)
            this.$set(this.formInline, timeMaxKey, undefined)
          }
          if (element.array2Date) {
            if (
              this.$func.isArray(element.array2Date) &&
              element.array2Date.length == 2
            ) {
              dateMinKey = element.array2Date[0]
              dateMaxKey = element.array2Date[1]
            } else {
              dateMinKey = element.array2Date + "_min"
              dateMaxKey = element.array2Date + "_max"
            }
            this.$set(this.formInline, dateMinKey, undefined)
            this.$set(this.formInline, dateMaxKey, undefined)
          }
          if (
            this.formInline[element.key] &&
            this.$func.isArray(this.formInline[element.key]) &&
            this.formInline[element.key].length > 0
          ) {
            let dates = this.formInline[element.key]
            if (element.array2Time) {
              if (dates.length > 0) {
                this.$set(
                  this.formInline,
                  timeMinKey,
                  parseInt(dates[0].startOf("day").valueOf() / 1000, 10)
                )
                this.$set(
                  this.formInline,
                  timeMaxKey,
                  parseInt(dates[1].endOf("day").valueOf() / 1000, 10)
                )
              }
            }
            if (element.array2Date) {
              if (dates.length > 0) {
                this.$set(
                  this.formInline,
                  dateMinKey,
                  dates[0].format("YYYY-MM-DD 00:00:00")
                )
                this.$set(
                  this.formInline,
                  dateMaxKey,
                  dates[1].format("YYYY-MM-DD 23:59:59")
                )
              }
            }
          }
          break
        case "date-picker":
          //单个日期的 Range 比较特殊，必须包括当天
          if (
            !element.value2Time &&
            !element.value2Date &&
            !element.value2RangeTime &&
            !element.value2RangeDate
          )
            break

          if (element.value2Time) {
            value2Time = element.value2Time
            this.$set(this.formInline, value2Time, undefined)
          }
          if (element.value2Date) {
            value2Date = element.value2Date
            this.$set(this.formInline, value2Date, undefined)
          }
          if (element.value2RangeTime) {
            if (
              this.$func.isArray(element.value2RangeTime) &&
              element.value2RangeTime.length == 2
            ) {
              timeMinKey = element.value2RangeTime[0]
              timeMaxKey = element.value2RangeTime[1]
            } else {
              timeMinKey = element.value2RangeTime + "_min"
              timeMaxKey = element.value2RangeTime + "_max"
            }
            this.$set(this.formInline, timeMinKey, undefined)
            this.$set(this.formInline, timeMaxKey, undefined)
          }
          if (element.value2RangeDate) {
            if (
              this.$func.isArray(element.value2RangeDate) &&
              element.value2RangeDate.length == 2
            ) {
              dateMinKey = element.value2RangeDate[0]
              dateMaxKey = element.value2RangeDate[1]
            } else {
              dateMinKey = element.value2RangeDate + "_min"
              dateMaxKey = element.value2RangeDate + "_max"
            }
            this.$set(this.formInline, dateMinKey, undefined)
            this.$set(this.formInline, dateMaxKey, undefined)
          }

          if (this.formInline[element.key]) {
            if (element.value2Time) {
              this.$set(
                this.formInline,
                value2Time,
                parseInt(
                  this.formInline[element.key].startOf("day").valueOf() / 1000,
                  10
                )
              )
            }
            if (element.value2Date) {
              this.$set(
                this.formInline,
                value2Date,
                this.formInline[element.key].format("YYYY-MM-DD")
              )
            }
            if (element.value2RangeTime) {
              this.$set(
                this.formInline,
                timeMinKey,
                parseInt(
                  this.formInline[element.key].startOf("day").valueOf() / 1000,
                  10
                )
              )
              this.$set(
                this.formInline,
                timeMaxKey,
                parseInt(
                  this.formInline[element.key].endOf("day").valueOf() / 1000,
                  10
                )
              )
            }
            if (element.value2RangeDate) {
              this.$set(
                this.formInline,
                dateMinKey,
                this.formInline[element.key].format("YYYY-MM-DD 00:00:00")
              )
              this.$set(
                this.formInline,
                dateMaxKey,
                this.formInline[element.key].format("YYYY-MM-DD 23:59:59")
              )
            }
          }
          break
        default:
          if (!element.array2Value) break
          this.$set(this.formInline, element.array2Value, undefined)
          if (
            this.formInline[element.key] &&
            this.$func.isArray(this.formInline[element.key]) &&
            this.formInline[element.key].length > 0
          ) {
            this.$set(
              this.formInline,
              element.array2Value,
              this.formInline[element.key].join(",")
            )
          }

          break
      }

      clearTimeout(this.timeoutObj)
      this.timeoutObj = setTimeout(() => {
        this.emitChange()
      }, 600)
    },
    emitChange() {
      for (let ii in this.formInline) {
        if (
          ii.substring(0, 3) == "rnd" &&
          this.formInline[ii] == ii.substring(3, ii.length)
        ) {
          this.$delete(this.formInline, ii)
        }
      }
      this.$emit("change", this.formInline)
    },
    emitClick() {
      for (let ii in this.formInline) {
        if (
          ii.substring(0, 3) == "rnd" &&
          this.formInline[ii] == ii.substring(3, ii.length)
        ) {
          this.$delete(this.formInline, ii)
        }
      }
      this.$emit("click", this.formInline)
    },
  },
}
</script>

<style lang="less" type="text/less" scoped></style>
